﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Downplay.Alchemy.Dynamic;

namespace Downplay.Alchemy.Tests.Dynamics {
    [TestFixture]
    public class MeldTests {


        [Test]
        public void CanMeldMultipleProperties() {
            dynamic stuff = new Stuff();
            stuff.Meld(new {
                Zoo = "Moo",
                Goo = 14
            });
            Assert.That((string)stuff.Zoo, Is.EqualTo("Moo"));
            Assert.That((int)stuff.Goo, Is.EqualTo(14));
        }

        [Test]
        public void CanOverrideMeldedProperties() {
            dynamic stuff = new Stuff();
            stuff.Meld(new {
                Zoo = "Moo",
                Goo = "Eww"
            });
            stuff.Meld(new {
                Goo = "Foo",
                Boo = "Who"
            });
            Assert.That((string)stuff.Zoo, Is.EqualTo("Moo"));
            Assert.That((string)stuff.Goo, Is.EqualTo("Foo"));
            Assert.That((string)stuff.Boo, Is.EqualTo("Who"));
        }

        [Test]
        public void CanMeldAndExtractInterface() {
            dynamic stuff = new Stuff();
            stuff.Meld(new {
                Zoo = "Moo",
                Goo = "Eww"
            });
            IZoo zoo = stuff;
            Assert.That(zoo.Zoo, Is.EqualTo("Moo"));
            Assert.That(zoo.Goo, Is.EqualTo("Eww"));
        }

        [Test]
        public void CanMeldDictionary() {
            dynamic stuff = new Stuff(new { Foo = "Moo", Zoo= "Who" });
            var dict = new Dictionary<string, object>{
                { "Foo", "Bar" },
                { "One", 1 },
                { "Silly", new string[] { "Stuff", "Is", "Fun" } }
            };
            stuff.Meld(dict);
            Assert.That((string)stuff.Zoo, Is.EqualTo("Who"));
            Assert.That((string)stuff.Foo, Is.EqualTo("Bar"));
            Assert.That((int)stuff.One, Is.EqualTo(1));
            Assert.That(stuff.Silly.Supertype(), Is.EqualTo("Array"));
            Assert.That(stuff.Silly.Count(), Is.EqualTo(3));
        }

        public interface IZoo {
            string Zoo { get; }
            string Goo { get; }
        }
        public class AZoo : IZoo {
            public string Zoo {
                get { return "Moo"; }
            }

            public string Goo {
                get { return "Eww"; }
            }
        }
    }
}
